package com.meida.common.utils;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.PinyinUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.meida.common.mybatis.entity.EntityMap;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.ibatis.io.Resources;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.*;

public class FlymeUtils {
    public FlymeUtils() {
    }

    /**
     * 其中一个为空
     *
     * @param objs
     * @return
     */
    public static boolean anyOneIsNull(Object... objs) {
        int n = objs.length;
        for (int i = 0; i < n; ++i) {
            Object o = objs[i];
            if (isEmpty(o)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 都为空
     *
     * @param objs
     * @return
     */
    public static boolean allIsNull(Object... objs) {
        int n = objs.length;
        int t = 0;
        for (int i = 0; i < n; ++i) {
            Object o = objs[i];
            if (isEmpty(o)) {
                t++;
            }
        }
        if (t == n) {
            return true;
        }
        return false;
    }

    /**
     * List转换为数组
     */
    public static <T> Long[] listToLong(List<T> list) {
        Long[] strs = list.toArray(new Long[list.size()]);
        return strs;
    }

    /**
     * v1>v2
     */
    public static Boolean gt(BigDecimal v1, BigDecimal v2) {
        Boolean tag = false;
        if (v1.compareTo(v2) == 1) {
            tag = true;
        }
        return tag;
    }

    /**
     * v1>=v2
     */
    public static Boolean ge(BigDecimal v1, BigDecimal v2) {
        Boolean tag = false;
        if (v1.compareTo(v2) == 1) {
            tag = true;
        }
        if (v1.compareTo(v2) == 0) {
            tag = true;
        }
        return tag;
    }

    /**
     * v1<v2
     */
    public static Boolean lt(BigDecimal v1, BigDecimal v2) {
        Boolean tag = false;
        if (v1.compareTo(v2) == -1) {
            tag = true;
        }
        return tag;
    }

    /**
     * v1=v2
     */
    public static Boolean eq(BigDecimal v1, BigDecimal v2) {
        Boolean tag = false;
        if (v1.compareTo(v2) == 0) {
            tag = true;
        }
        return tag;
    }

    /**
     * 判断BigDecimal是否小于等于0
     */
    public static Boolean le(BigDecimal v1, BigDecimal v2) {
        Boolean tag = false;
        if (v1.compareTo(v2) == -1) {
            tag = true;
        }
        if (v1.compareTo(v2) == 0) {
            tag = true;
        }
        return tag;
    }

    /**
     * 判断BigDecimal是否大于0
     */
    public static Boolean gtzero(BigDecimal v) {
        Boolean tag = false;
        if (ObjectUtils.isNotEmpty(v)) {
            if (v.doubleValue() > 0) {
                tag = true;
            }
        }
        return tag;
    }

    /**
     * 判断BigDecimal是否大于等于0
     */
    public static Boolean gezero(BigDecimal v) {
        Boolean tag = false;
        if (ObjectUtils.isNotEmpty(v)) {
            if (v.compareTo(new BigDecimal("0.0")) == 0 || v.compareTo(new BigDecimal("0.0")) == 1) {
                tag = true;
            }
        }
        return tag;
    }

    /**
     * 判断BigDecimal是等于0
     */
    public static Boolean eqzero(BigDecimal v) {
        Boolean tag = false;
        if (ObjectUtils.isNotEmpty(v)) {
            if (v.compareTo(new BigDecimal("0.0")) == -1) {
                tag = true;
            }
        }
        return tag;
    }

    /**
     * 判断BigDecimal不等于0
     */
    public static Boolean nezero(BigDecimal v) {
        Boolean tag = true;
        if (ObjectUtils.isNotEmpty(v)) {
            if (v.compareTo(new BigDecimal("0.0")) == 0) {
                tag = false;
            }
        }
        return tag;
    }

    /**
     * 判断BigDecimal是否xiao于0
     */
    public static Boolean ltzero(BigDecimal v) {
        Boolean tag = false;
        if (ObjectUtils.isNotEmpty(v)) {
            if (v.doubleValue() < 0) {
                tag = true;
            }
        }
        return tag;
    }

    /**
     * 判断BigDecimal是否小于等于0
     */
    public static Boolean lezero(BigDecimal v) {
        Boolean tag = false;
        if (ObjectUtils.isNotEmpty(v)) {
            if (v.compareTo(new BigDecimal("0.0")) == 0) {
                tag = true;
            }
            if (v.compareTo(new BigDecimal("0.0")) == -1) {
                tag = true;
            }
        }
        return tag;
    }

    /**
     * 判断某个字符串是否存在于数组中
     */
    public static boolean contains(String[] stringArray, String source) {
        List<String> tempList = Arrays.asList(stringArray);
        if (tempList.contains(source)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断某个字符串是否存在于数组中
     */
    public static boolean contains(List<String> stringArray, String source) {
        if (stringArray.contains(source)) {
            return true;
        } else {
            return false;
        }

    }

    public static String[] getNullPropertyNames(Object source, String[] fields) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<String>();
        if (ObjectUtils.isNotEmpty(fields)) {
            for (String str : fields) {
                emptyNames.add(str);
            }
        }
        for (java.beans.PropertyDescriptor pd : pds) {
            String name = pd.getName();
            if (name.equals("callback") || name.equals("callbacks") || name.equals("class")) {
                break;
            }
            Object srcValue = src.getPropertyValue(pd.getName());
            if (ObjectUtils.isEmpty(srcValue)) {
                emptyNames.add(pd.getName());
            }

        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }


    /**
     * 对象属性拷贝
     */
    public static void copy(Object source, Object target, String... fields) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source, fields));
    }


    /**
     * 都不为空
     *
     * @param obj
     * @return
     */
    public static boolean allNotNull(Object... obj) {
        return !anyOneIsNull(obj);
    }

    public static boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }

    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        } else if (obj.getClass().isArray()) {
            return Array.getLength(obj) == 0;
        } else if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        } else if ((obj instanceof String)) {
            return ((String) obj).trim().equals("");
        } else if (obj instanceof Collection) {
            return ((Collection) obj).isEmpty();
        } else {
            return obj instanceof Map ? ((Map) obj).isEmpty() : false;
        }
    }

    /**
     * 以UUID重命名
     *
     * @param fileName
     * @return
     */
    public static String renamePic(String fileName) {
        String extName = fileName.substring(fileName.lastIndexOf("."));
        return UUID.randomUUID().toString().replace("-", "") + extName;
    }


    /**
     *
     */
    public static BigDecimal getBigDecimal(BigDecimal v, String defval) {
        if (ObjectUtils.isEmpty(v)) {
            return new BigDecimal(defval);
        }
        return v;
    }


    /**
     *
     */
    public static String getString(String v, String defval) {
        if (isEmpty(v)) {
            return defval;
        }
        return v;
    }

    /**
     *
     */
    public static Integer getInteger(Integer v, Integer defval) {
        if (ObjectUtils.isEmpty(v)) {
            return defval;
        }
        return v;
    }

    /**
     *
     */
    public static Long getLong(Object v) {
        if (ObjectUtils.isEmpty(v)) {
            return null;
        }
        return Long.parseLong(v.toString());
    }

    /**
     *
     */
    public static Long getLong(Object v, Long def) {
        if (ObjectUtils.isEmpty(v)) {
            return def;
        }
        return Long.parseLong(v.toString());
    }

    /**
     * 中文數字转阿拉伯数组【十万九千零六十  --> 109060】
     */
    @SuppressWarnings("unused")
    public static String chineseNumber2Int(String chineseNumber) {
        String[] s1 = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        String[] s2 = {"十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千"};
        String result = "";
        int n = chineseNumber.length();
        for (int i = 0; i < n; i++) {
            int num = chineseNumber.charAt(i) - '0';
            if (i != n - 1 && num != 0) {
                result += s1[num] + s2[n - 2 - i];
            } else {
                result += s1[num];
            }
            System.out.println("  " + result);
        }
        return result;
    }


    public static <T> T getEntity(Class<T> t, EntityMap requestMap) {
        if (FlymeUtils.isNotEmpty(requestMap)) {
            Map<Object, Object> map = new HashMap<>();
            map.putAll(requestMap);
            return JsonUtils.jsonToBean(JSONUtil.toJsonStr(map), t);
        } else {
            return null;
        }

    }

    public static String getAlias(String tableName) {
        String[] str = tableName.split("_");
        String alias = "";
        if (str.length > 2) {
            for (String s : str) {
                alias += s.substring(0, 1);
            }
        } else {
            alias = str[str.length - 1];
        }
        return alias;
    }

    /**
     * 字符串转换unicode
     */
    public static String string2Unicode(String string) {
        String result = "";
        if (ObjectUtils.isNotEmpty(string)) {
            StringBuffer unicode = new StringBuffer();
            for (int i = 0; i < string.length(); i++) {
                // 取出每一个字符
                char c = string.charAt(i);
                // 转换为unicode
                unicode.append("\\u" + Integer.toHexString(c));
            }
            result = unicode.toString();
        }
        return result;
    }

    public static Long[] StringArray2LongArray(String[] stringArray) {
        List<Long> list = new ArrayList<>();
        for (String str : stringArray) {
            try {
                list.add(Long.parseLong(str));
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        Long[] longArray = list.toArray(new Long[list.size()]);
        return longArray;
    }

    /**
     * unicode 转字符串
     */
    public static String unicode2String(String unicode) {
        String result = "";
        if (ObjectUtils.isNotEmpty(unicode)) {
            StringBuffer string = new StringBuffer();
            String[] hex = unicode.split("\\\\u");
            for (int i = 1; i < hex.length; i++) {
                // 转换出每一个代码点
                int data = Integer.parseInt(hex[i], 16);
                // 追加成string
                string.append((char) data);
            }
            result = string.toString();
        }
        return result;
    }

    public static Reader getResource(String resource) {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return reader;
    }

    public static Long[] stringToLong(String [] stringArray) {
        if (stringArray == null) {
            return null;
        }
        return (Long[]) ConvertUtils.convert(stringArray, Long.class);
    }

    public static String getClassPathResoruce(String path) {
        ClassPathResource resource = new ClassPathResource(path);
        return IoUtil.read(resource.getStream(), "UTF-8");
    }

    public static Boolean contains(Object[] objs, Object obj) {
        return Arrays.asList(objs).contains(obj);
    }

    public  static  void main(String[] args){
        System.out.println(PinyinUtil.getPinYin("测试Test"));
    }

}
